﻿namespace Probel.NDoctor.Statistics.Console.Menus
{
    using System;
    using System.Collections.Generic;
    using System.Linq;

    internal class Menu : ICommand
    {
        #region Fields

        private readonly Dictionary<int, MenuItem> Commands = new Dictionary<int, MenuItem>();

        #endregion Fields

        #region Constructors

        public Menu(string title)
            : this(string.Empty, title)
        {
        }

        public Menu(string exitValue, string title)
        {
            this.Title = title;
            this.ExitValue = exitValue;
            this.Continue = true;
        }

        #endregion Constructors

        #region Properties

        public bool Continue
        {
            get;
            private set;
        }

        private string ExitValue
        {
            get;
            set;
        }

        private int LastIndex
        {
            get
            {
                if (this.Commands.Count() > 0)
                {
                    return this.Commands.Keys.Max();
                }
                else { return 0; }
            }
        }

        private string Title
        {
            get;
            set;
        }

        #endregion Properties

        #region Methods

        public void Add(ICommand command, string title)
        {
            this.Commands.Add(LastIndex + 1, new MenuItem(command, title));
        }

        public void Execute()
        {
            do
            {
                Output.Clear();
                this.Dislay();
                this.AskUserChoice();
            } while (this.Continue);
        }

        private void AskUserChoice()
        {
            var choice = Output.ReadLine("Enter you choice: ");
            this.Execute(choice);
        }

        private void Dislay()
        {
            var items = this.Commands.OrderBy(e => e.Key);

            Output.WriteLine(Environment.NewLine
                + this.Title
                + Environment.NewLine
                + "-----");

            foreach (var item in items)
            {
                Output.WriteLine("{0,3} - {1}"
                    , item.Key
                    , item.Value.Title);
            }
        }

        private void Execute(string menu)
        {
            int i = 0;
            if (int.TryParse(menu, out i))
            {
                if (this.Commands.ContainsKey(i))
                {
                    Output.Clear();
                    this.Commands[i].Command.Execute();
                }
                else
                {
                    Output.WriteLine("This menu doesn't exist");
                    Output.Pause();
                }
            }
            else
            {
                if (menu.ToLower() == this.ExitValue.ToLower())
                {
                    menu = this.ExitValue + "'(§"; //Avoid the menu to be reset ;)
                    this.Continue = false;
                }
                else { Output.WriteLine("Unknown menu"); }
            }
        }

        #endregion Methods
    }
}